/*
 *  Copyright (C) 2009  Peter Kist & Jan Ripke
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __input_ois_manager_h
#define __input_ois_manager_h 1

#include <boost/enable_shared_from_this.hpp>

#include <Modules/Input/OIS/Types.h>

#include <Core/Kernel/ModuleManager.h>
#include <Util/Types.h>

namespace OIS {
    class InputManager;
    class Mouse;
    class Keyboard;
}

namespace galaxy {

    namespace mediator {
        class Event;
    }

    namespace gfx {
        class GfxRequestWinInfo;
    }

    namespace input {

        namespace ois_input {

            // forward declarations
            class Consumer;
            class Producer;
            class Manager;
            class KeyMapper;

            /** Handles the input capture thread. It captures input from keyboard, mouse and joystick.
            * The registerd event handlers are called automatically be the capture process
            */
            class InputHandlerThread {
            public:
                ManagerPtr          m_Manager;
                util::Thread::State m_State;

                InputHandlerThread() { };
                InputHandlerThread(InputHandlerThread& source) { m_Manager = source.m_Manager; };
                InputHandlerThread(ManagerPtr& manager) { m_Manager = manager; };

                void operator()();
            };

            /**
            * This class is the main entry point to the input module.
            * The implementation makes use of the Ogre 3D / OIS engine.
            */
            class Manager : public boost::enable_shared_from_this<Manager>,
                public galaxy::ModuleManager
            {
                friend class KeyEventHandler;
                friend class MouseEventHandler;
                friend class InputHandlerThread;

            private:
                
                ProducerPtr         m_Producer;             /**< gfx module producer */
                ConsumerPtr         m_Consumer;             /**< gfx module consumer */
                KeyMapperPtr        m_KeyMap;               /**< key mapper */

                // input system and devices //
                OIS::InputManager  * m_InputManager;        /**< the OIS Input Manager */
                OIS::Mouse         * m_Mouse;               /**< the OIS mouse device */
                OIS::Keyboard      * m_Keyboard;            /**< the OIS keyboard device */

                // event handlers //
                KeyEventHandler    * m_KeyEventHandler;     /**< handles all key events */
                MouseEventHandler  * m_MouseEventHandler;   /**< handles all mouse events */

                InputHandlerThread * m_InputHandlerThread;  /**< thread that captures input */

            public:

                Manager(void);
                virtual ~Manager(void);

                // ModuleManager interface
                virtual const char *    moduleName () { return "INPUT Module"; };
                virtual bool            initialize ();
                virtual bool            postInitialize ();
                virtual boost::thread * startManagerThread ();
                virtual void            terminateThread ();
                virtual bool            preDestroy ();
                virtual bool            destroy ();

                KeyMapperPtr getKeyMap () { return m_KeyMap; };

            private:
                bool setupInputSystem (gfx::GfxRequestWinInfo const & winInfo);
                void initializeKeyMapper();

                void capture( void ); 

                bool terminate ();
            };

            

        } // namespace ois_input

    } // namespace input

} // namespace galaxy

#endif // __input_ois_manager_h
